<template>
  <div class="sky_video_box">
    <video
      class="sky_video"
      ref="videos"
      :src="url"
      :poster="poster"
      playsinline="true"
      webkit-playsinline="true"
      x5-playsinline="true"
      x5-video-player-type="h5"
      x5-video-orientation="portraint"
      x5-video-player-fullscreen="false"
      mediatype="video"
    >
      您的浏览器不支持 video 标签。
    </video>
    <div class="sky_player_control_wrap" @click="clickShowVideoControl">
      <i
        class="iconfont icon-bofang5 big"
        v-show="videoIsPaused"
        @click.stop="playVideo"
      ></i>
      <!-- 底部操作 -->
      <div class="sky_player_control_bottom u-f" v-show="showVideoControl">
        <div class="icon_box u-f u-f-ac u-f-jc">
          <i
            class="iconfont icon-bofang5"
            v-show="videoIsPaused"
            @click.stop="playVideo"
          ></i>
          <i
            class="iconfont icon-zantingtingzhi"
            v-show="!videoIsPaused"
            @click.stop="pauseVideo"
          ></i>
        </div>
        <div class="slider_box u-f u-f-ac u-f-jsb u-f1">
          <span class="play_time">{{ playTime }}</span>
          <van-slider
            v-model="slider"
            inactive-color="var(--sky-text-gray4-color)"
            active-color="var(--sky-text-gray6-color)"
            :button-size="8"
            @change="onSliderChange"
          />
          <span class="all_time">{{ allTime }}</span>
        </div>
        <div class="icon_box u-f u-f-ac u-f-jc" @click.stop="changeVideoMuted">
          <i class="iconfont icon-shengyin" v-show="!videoIsMuted"></i>
          <i
            class="iconfont icon-yinliangjingyinhei2x"
            v-show="videoIsMuted"
          ></i>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import {
  computed,
  ComputedRef,
  defineComponent,
  onMounted,
  ref,
  Ref,
  watch,
} from 'vue'
import { formatTime } from '@/assets/ts/util'
import { useStore } from 'vuex'

const handleChangeVideo = (
  props: any,
  videos: Ref<any>,
  duration: ComputedRef<number>
) => {
  let timer: number | undefined = undefined
  const store = useStore()
  const slider: Ref<number> = ref(0)
  const playTime: Ref<string> = ref('00:00')

  const videoIsPaused: Ref<boolean> = ref(true)
  const videoIsMuted: Ref<boolean> = ref(false)

  const showVideoControl: Ref<boolean> = ref(false)

  const clickShowVideoControl = () => {
    clearTimeout(timer)
    if (videoIsPaused.value) {
      playVideo()
    }
    showVideoControl.value = true
    timer = setTimeout(() => {
      showVideoControl.value = false
    }, 3000)
  }

  const playVideo = () => {
    // 播放
    if (!videos.value) return
    videos.value.play()
    videoIsPaused.value = false
    store.commit('setCurrentVideoPlaying', props.url)
  }

  const pauseVideo = () => {
    // 暂停
    if (!videos.value) return
    videos.value.pause()
    videoIsPaused.value = true
  }

  const endVideo = () => {
    videoIsPaused.value = true
  }

  const changeVideoMuted = () => {
    if (videoIsMuted.value) {
      videos.value.muted = false
      videoIsMuted.value = false
    } else {
      videos.value.muted = true
      videoIsMuted.value = true
    }
  }

  const updateSlider = () => {
    // 这个时间精度到秒，用于进度条显示
    const time = Math.floor(videos.value?.currentTime || 0)

    playTime.value = formatTime(time)

    const b = (time / duration.value) * 100
    slider.value = Number(b.toFixed(1))
  }

  // 手动点击滑块
  const onSliderChange = (value: number) => {
    if (!videos.value.paused || videos.value.currentTime !== 0) {
      const time = Math.floor((duration.value * value) / 100)
      videos.value.currentTime = time
      playTime.value = formatTime(time)
    }
  }

  onMounted(() => {
    videos.value.addEventListener('ended', () => {
      // 监听播放结束
      endVideo()
    })

    videos.value.addEventListener('timeupdate', () => {
      // 监听播放位置发生改变
      updateSlider()
    })
  })

  watch(
    () => store.state.currentVideoPlaying,
    (newVal, oldVal) => {
      if (newVal !== oldVal) {
        pauseVideo()
        if (newVal === props.url) {
          playVideo()
        }
      }
    },
    {
      immediate: true,
    }
  )

  return {
    slider,
    playTime,
    videoIsPaused,
    videoIsMuted,
    showVideoControl,
    onSliderChange,
    playVideo,
    pauseVideo,
    changeVideoMuted,
    clickShowVideoControl,
  }
}

export default defineComponent({
  name: 'SkyVideo',
  props: {
    url: {
      type: String,
      default: '',
    },
    poster: {
      // 未播放前显示的图片
      type: String,
      default: '',
    },
    muted: {
      // 是否静音
      type: Boolean,
      default: false,
    },
    time: {
      type: Number,
      default: 0,
    },
  },
  setup(props) {
    const videos: Ref<any> = ref(null)

    const duration = computed(() => {
      return props.time
    })

    const allTime = computed(() => {
      return formatTime(props.time)
    })

    const {
      slider,
      playTime,
      videoIsPaused,
      videoIsMuted,
      showVideoControl,
      onSliderChange,
      playVideo,
      pauseVideo,
      changeVideoMuted,
      clickShowVideoControl,
    } = handleChangeVideo(props, videos, duration)

    return {
      videos,
      duration,
      allTime,
      slider,
      playTime,
      videoIsPaused,
      videoIsMuted,
      showVideoControl,
      onSliderChange,
      playVideo,
      pauseVideo,
      changeVideoMuted,
      clickShowVideoControl,
    }
  },
})
</script>

<style lang="less">
.sky_video_box {
  position: relative;
  width: 100%;
  height: 100%;
  .sky_video {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    outline: none;
  }
  .sky_player_control_wrap {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 2;
    .icon-bofang5.big {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      font-size: 30px;
      color: var(--sky-text-white-color);
      z-index: 5;
    }
    .sky_player_control_bottom {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      height: 40px;
      z-index: 4;
      .slider_box {
        padding: 0 16px;
        .play_time {
          display: inline-block;
          font-size: 14px;
          color: var(--sky-text-white-color);
          margin-right: 10px;
        }
        .all_time {
          display: inline-block;
          font-size: 14px;
          color: var(--sky-text-white-color);
          margin-left: 10px;
        }
      }
      .icon_box {
        width: 30px;
        .icon-bofang5 {
          font-size: 16px;
          color: var(--sky-text-white-color);
        }
        .icon-zantingtingzhi {
          font-size: 30px;
          color: var(--sky-text-white-color);
        }
        .icon-shengyin {
          font-size: 22px;
          color: var(--sky-text-white-color);
        }
        .icon-yinliangjingyinhei2x {
          font-size: 22px;
          color: var(--sky-text-white-color);
        }
      }
    }
  }
}
</style>